package com.lb.ai.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * JSON工具类
 *
 * @author LiuB
 * @version 1.1
 */
@Slf4j
@Component
public class JsonUtils {

    /**
     * 默认日期格式
     */
    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * 默认时区
     */
    private static final String DEFAULT_TIME_ZONE = "GMT+8";

    /**
     * Spring注入的ObjectMapper实例
     */
    @Autowired(required = false)
    private ObjectMapper springObjectMapper;

    /**
     * 实际使用的ObjectMapper实例
     */
    private static ObjectMapper OBJECT_MAPPER;

    /**
     * 默认的ObjectMapper实例
     */
    private static final ObjectMapper DEFAULT_OBJECT_MAPPER = createDefaultObjectMapper();

    /**
     * 初始化方法，优先使用Spring注入的ObjectMapper，如果没有则使用默认配置
     * 该方法在Spring容器启动时自动执行
     */
    @PostConstruct
    public void init() {
        OBJECT_MAPPER = springObjectMapper != null ? springObjectMapper : DEFAULT_OBJECT_MAPPER;
        log.info("JsonUtils初始化完成，使用{}", springObjectMapper != null ? "Spring注入实例" : "默认实例");
    }

    /**
     * 创建默认的ObjectMapper实例
     * 配置了序列化、反序列化特性和日期处理
     *
     * @return 配置完善的ObjectMapper实例
     */
    private static ObjectMapper createDefaultObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();

        // 配置序列化特性
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT, false);

        // 配置反序列化特性
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);

        // 配置日期格式
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
        dateFormat.setTimeZone(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        objectMapper.setDateFormat(dateFormat);

        return objectMapper;
    }

    /**
     * 获取当前使用的ObjectMapper实例
     * 如果OBJECT_MAPPER未初始化，则返回默认实例
     *
     * @return ObjectMapper实例，不会返回null
     */
    public static ObjectMapper getObjectMapper() {
        if (OBJECT_MAPPER == null) {
            log.warn("OBJECT_MAPPER未初始化，使用默认实例");
            return DEFAULT_OBJECT_MAPPER;
        }
        return OBJECT_MAPPER;
    }

    /**
     * 将对象转换为JSON字符串
     *
     * @param obj 待转换的对象，可以是任何类型
     * @return 转换后的JSON字符串，如果转换失败或输入为null则返回null
     */
    public static String toJsonString(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return getObjectMapper().writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("对象转JSON失败：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 将JSON字符串转换为指定类型的对象
     *
     * @param jsonString JSON字符串
     * @param clazz      目标类型的Class对象
     * @param <T>        目标类型
     * @return 转换后的对象，如果转换失败或输入为空则返回null
     */
    public static <T> T parseObject(String jsonString, Class<T> clazz) {
        if (jsonString == null || jsonString.isEmpty()) {
            return null;
        }
        try {
            return getObjectMapper().readValue(jsonString, clazz);
        } catch (JsonProcessingException e) {
            log.error("JSON转对象失败，类型：{}，异常：{}", clazz.getSimpleName(), e.getMessage());
            return null;
        }
    }

    /**
     * 将JSON字符串转换为List集合
     *
     * @param jsonString JSON字符串
     * @param clazz      List中元素的类型
     * @param <T>        元素类型
     * @return 转换后的List集合，如果转换失败或输入为空则返回空List
     */
    public static <T> List<T> parseArray(String jsonString, Class<T> clazz) {
        if (jsonString == null || jsonString.isEmpty()) {
            return new ArrayList<>();
        }
        try {
            JavaType javaType = getObjectMapper().getTypeFactory().constructParametricType(List.class, clazz);
            return getObjectMapper().readValue(jsonString, javaType);
        } catch (JsonProcessingException e) {
            log.error("JSON转List失败，元素类型：{}，异常：{}", clazz.getSimpleName(), e.getMessage());
            return new ArrayList<>();
        }
    }

    /**
     * 将JSON字符串转换为Map集合
     *
     * @param jsonString JSON字符串
     * @return 转换后的Map集合，如果转换失败或输入为空则返回空Map
     */
    public static Map<String, Object> parseMap(String jsonString) {
        if (jsonString == null || jsonString.isEmpty()) {
            return new HashMap<>();
        }
        try {
            return getObjectMapper().readValue(jsonString, new TypeReference<Map<String, Object>>() {});
        } catch (JsonProcessingException e) {
            log.error("JSON转Map失败：{}", e.getMessage());
            return new HashMap<>();
        }
    }

    /**
     * 将JSON字符串转换为复杂的泛型类型
     * 适用于复杂的泛型类型，例如嵌套的集合类型
     *
     * @param jsonString    JSON字符串
     * @param typeReference 类型引用，用于处理复杂的泛型类型
     * @param <T>           目标类型
     * @return 转换后的对象，如果转换失败或输入为空则返回null
     */
    public static <T> T parseComplexType(String jsonString, TypeReference<T> typeReference) {
        if (jsonString == null || jsonString.isEmpty()) {
            return null;
        }
        try {
            return getObjectMapper().readValue(jsonString, typeReference);
        } catch (JsonProcessingException e) {
            log.error("JSON转复杂类型失败，类型：{}，异常：{}", 
                    typeReference.getType().getTypeName(), e.getMessage());
            return null;
        }
    }

    /**
     * 判断字符串是否为有效的JSON格式
     *
     * @param jsonString 待验证的JSON字符串
     * @return true:有效的JSON字符串，false:无效的JSON字符串或空字符串
     */
    public static boolean isValidJson(String jsonString) {
        if (jsonString == null || jsonString.isEmpty()) {
            return false;
        }
        try {
            getObjectMapper().readTree(jsonString);
            return true;
        } catch (JsonProcessingException e) {
            return false;
        }
    }
} 